/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package simulation;

import jade.core.behaviours.CyclicBehaviour;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import java.util.List;
import persistence.DataReader;
import persistence.DataWriter;

/**
 *
 * @author Danielondon
 */
public class MarketAgent extends SimulationAgent {
    
    String fileName;
    Market market;

    @Override
    public void setup(){
        super.setup();
        // This need to be readjusted somehow in case the user wants to change the mode
        // after it runs     
        //this.SLOT_SIZE = 15;
        //this.TOTAL_SLOTS = 96;
       // this.setCustomParameters(this.getArguments());
        
        // Register the Price Request service in the yellow pages
        ServiceDirectory.registerAgentService(this, ServiceSimulationDescription.PRICE_REQUEST);
        
        // Add the behavior offering the price
        //AID [] controllerAgents = ServiceDirectory.getProvidersFromService(this, ServiceSimulationDescription.SIMULATION_LISTENER);
        //if ( controllerAgents != null && controllerAgents.length != 0) {
        //    this.controllerAgent = controllerAgents[0];
        //    System.out.println("Found agents for simulation " + controllerAgents.length);
        this.addBehaviour(new SendMessage("market", this.controllerAgent , ACLMessage.INFORM));
        //}
        this.addBehaviour(new PriceRequestService());
        
    }

    @Override
    protected void setCustomParameters(Object[] arguments) {    
        this.fileName = (String) arguments[3];        
        this.loadMarketData();
    }

    private void loadMarketData() {
        try {
            if (this.TOTAL_SLOTS == 0)
                return;
            
            // TODO: Verify that the data laoded correspond to the amount of slots
            DataReader fileReader = new DataReader(fileName);
            List<String[]> data = fileReader.getData();
            double []pricePerSlot = new double[this.TOTAL_SLOTS];
            for (int i = 0; i < pricePerSlot.length; i++){
                pricePerSlot[i] = Double.parseDouble(data.get(i)[DataWriter.PRICE_INDEX]);
            }
            
            //TODO: Adjust name
            this.market = new Market(fileName, pricePerSlot, this.TOTAL_SLOTS, this.SLOT_SIZE, CommonResources.DEFAULT_CURRENCY);
            logger.info("Market Data Loaded " + this.TOTAL_SLOTS + " slots.");
            
        } catch (Exception ex) {
            logger.error(ex);
            this.doDelete();
        }
        
    }
    
    /**
     * Behavior to handle the price requests.
     */
    private class PriceRequestService extends CyclicBehaviour {
        /**
         * Action to execute every cycle. 
         * It waits for a message, otherwise it blocks until new message is available.
         */
        @Override
        public void action() {
            //MessageTemplate mt = MessageTemplate.or(MessageTemplate.MatchPerformative(ACLMessage.CFP),MessageTemplate.MatchPerformative(ACLMessage.INFORM));
            MessageTemplate mt = MessageTemplate.or( MessageTemplate.MatchPerformative(ACLMessage.CFP),  
                    MessageTemplate.MatchPerformative(ACLMessage.REQUEST));
            ACLMessage msg = myAgent.receive(mt);
            if (msg != null) {
                if (msg.getPerformative() == ACLMessage.CFP) {
                    // CFP Message received. Process it
                    ACLMessage reply = msg.createReply();                    
                    reply.setPerformative(ACLMessage.INFORM);
                    reply.setContent(market.toString());                
                    myAgent.send(reply);
                } else if (msg.getPerformative() == ACLMessage.REQUEST) {
                    setParameters(CommonResources.ParametersToObjectArray(msg.getContent()));
                    //setCustomParameters(getArguments());
                }
            } else {
                block();
            }
        }
    }
}
